package RMIClient.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.RemoteException;
import java.sql.SQLException;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;
import javax.swing.SwingUtilities;

import authorizationRMI.InvalidPasswordException;
import authorizationRMI.InvalidUserException;

import raceReservationServer.RaceRMIDTO;
import raceReservationServer.loginGateway.ValidationException;

import RMIClient.RaceRemoteObserver;
import RMIClient.RunnerRMIDTO;
import RMIClient.RaceController;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class ClientGUI extends javax.swing.JFrame implements Observer{
	private JDesktopPane runnerDetails;
	private JDesktopPane racePlaceAvailability;
	private JTextField passField;
	private JTextField ageField;
	private AbstractAction exit;
	private AbstractAction reservePlace;
	private AbstractAction getRaces;
	private JLabel errorLaber;
	private AbstractAction login;
	private JButton exitButton;
	private JButton reserveButton;
	private JButton getRacesButton;
	private JTable racesTable;
	private JButton loginButton;
	private JLabel sexLabel;
	private JLabel ageLabel;
	private JLabel passLabel;
	private JLabel nameLabel;
	private JLabel userNameLabel;
	private JTextField sexField;
	private JTextField nameField;
	private JTextField userNameField;
	private JDesktopPane jDesktopPane1;
	private RaceController controller;
	private DefaultTableModel racesTableModel; 


	/**
	* Auto-generated main method to display this JFrame
	*/
	
	public ClientGUI(RaceController rController) {
		super();
		controller=rController;
		initGUI();
		this.setVisible(true);
	}
	
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			{
				runnerDetails = new JDesktopPane();
				getContentPane().add(runnerDetails, BorderLayout.NORTH);
			}
			{
				racePlaceAvailability = new JDesktopPane();
				getContentPane().add(racePlaceAvailability, BorderLayout.SOUTH);
				racePlaceAvailability.setPreferredSize(new java.awt.Dimension(735, 276));
				racePlaceAvailability.setBackground(new java.awt.Color(255,255,255));
				{
					racesTableModel = 
						new DefaultTableModel(
								new String[][] {{  "RaceServer", "RaceName", "Distance", "Date", "Places" }},
								new String[] { "Column 1", "Column 2", "Column 3", "Column 4", "Column5" });
					racesTable = new JTable(){
						public boolean isCellEditable(int rowIndex, int colIndex){
							return false;
						}
					};
					racePlaceAvailability.add(racesTable, JLayeredPane.DEFAULT_LAYER);
					racesTable.setModel(racesTableModel);
					racesTable.setBounds(56, 22, 619, 157);
					racesTable.setRowSelectionAllowed(true);
				
				}
				{
					getRacesButton = new JButton();
					racePlaceAvailability.add(getRacesButton, JLayeredPane.DEFAULT_LAYER);
					getRacesButton.setText("Get Scheduled Races");
					getRacesButton.setBounds(68, 218, 183, 21);
					getRacesButton.setAction(getGetRaces());
					getRacesButton.setEnabled(false);
				}
				{
					reserveButton = new JButton();
					racePlaceAvailability.add(reserveButton, JLayeredPane.DEFAULT_LAYER);
					reserveButton.setText("Reserve Place");
					reserveButton.setBounds(314, 218, 148, 21);
					reserveButton.setAction(getReservePlace());
					reserveButton.setEnabled(false);
				}
				{
					exitButton = new JButton();
					racePlaceAvailability.add(exitButton, JLayeredPane.DEFAULT_LAYER);
					exitButton.setText("Exit");
					exitButton.setBounds(570, 218, 92, 21);
					exitButton.setAction(getExit());
				}
			}
			{
				jDesktopPane1 = new JDesktopPane();
				getContentPane().add(jDesktopPane1, BorderLayout.NORTH);
				jDesktopPane1.setPreferredSize(new java.awt.Dimension(735, 193));
				jDesktopPane1.setBackground(new java.awt.Color(255,255,255));
				{
					userNameField = new JTextField();
					jDesktopPane1.add(userNameField, JLayeredPane.DEFAULT_LAYER);
					userNameField.setBounds(112, 28, 173, 21);
				}
				{
					nameField = new JTextField();
					jDesktopPane1.add(nameField, JLayeredPane.DEFAULT_LAYER);
					nameField.setBounds(112, 78, 264, 21);
				}
				{
					passField = new JTextField();
					jDesktopPane1.add(passField, JLayeredPane.DEFAULT_LAYER);
					passField.setBounds(526, 28, 148, 21);
				}
				{
					ageField = new JTextField();
					jDesktopPane1.add(ageField, JLayeredPane.DEFAULT_LAYER);
					ageField.setBounds(469, 78, 72, 21);
				}
				{
					sexField = new JTextField();
					jDesktopPane1.add(sexField, JLayeredPane.DEFAULT_LAYER);
					sexField.setBounds(612, 78, 62, 21);
				}
				{
					userNameLabel = new JLabel();
					jDesktopPane1.add(userNameLabel, JLayeredPane.DEFAULT_LAYER);
					userNameLabel.setText("Username");
					userNameLabel.setBounds(22, 31, 72, 14);
				}
				{
					nameLabel = new JLabel();
					jDesktopPane1.add(nameLabel, JLayeredPane.DEFAULT_LAYER);
					nameLabel.setText("Name");
					nameLabel.setBounds(22, 81, 53, 14);
				}
				{
					passLabel = new JLabel();
					jDesktopPane1.add(passLabel, JLayeredPane.DEFAULT_LAYER);
					passLabel.setText("Password");
					passLabel.setBounds(428, 31, 80, 14);
				}
				{
					ageLabel = new JLabel();
					jDesktopPane1.add(ageLabel, JLayeredPane.DEFAULT_LAYER);
					ageLabel.setText("Age");
					ageLabel.setBounds(428, 81, 29, 14);
				}
				{
					sexLabel = new JLabel();
					jDesktopPane1.add(sexLabel, JLayeredPane.DEFAULT_LAYER);
					sexLabel.setText("Sex");
					sexLabel.setBounds(573, 81, 27, 14);
				}
				{
					loginButton = new JButton();
					jDesktopPane1.add(loginButton, JLayeredPane.DEFAULT_LAYER);
					jDesktopPane1.add(getErrorLaber(), JLayeredPane.DEFAULT_LAYER);
					loginButton.setText("Login");
					loginButton.setBounds(319, 133, 99, 21);
					loginButton.setAction(getLogin());
				}
			}
			pack();
			this.setSize(743, 500);
			this.setResizable(false);
			Color color= new Color(100);
			this.setBackground(color);
			this.setDefaultCloseOperation (0);

			this.addWindowListener ( new WindowAdapter () {
			  public void windowClosing (WindowEvent e) {
				  try {
					controller.exit();
				} catch (RemoteException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			  }
			});
		} catch (Exception e) {
		    //add your error handling code here
			e.printStackTrace();
		}
	}
	
	private AbstractAction getLogin() {
		if(login == null) {
			login = new AbstractAction("Login", null) {
				public void actionPerformed(ActionEvent evt) {
					errorLaber.setText("");
					String userName= userNameField.getText();
					String pass= passField.getText();
					try {
						RunnerRMIDTO runner=controller.login(userName, pass);
						nameField.setText(runner.getName());
						ageField.setText(Integer.toString(runner.getAge()));
						sexField.setText(runner.getSex());
						if (runner!=null){
							nameField.setEditable(false);
							ageField.setEditable(false);
							sexField.setEditable(false);
							errorLaber.setText("Push 'Get Schedulled races' button to list the available races");
							getGetRaces();
							getRacesButton.setEnabled(true);
						}
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						errorLaber.setText("Remote exception");
						getRacesButton.setEnabled(false);
						reserveButton.setEnabled(false);
					} catch (InvalidUserException e){
						errorLaber.setText("The user does not exist");
						getRacesButton.setEnabled(false);
						reserveButton.setEnabled(false);
					} catch (InvalidPasswordException e) {
						// TODO Auto-generated catch block
						errorLaber.setText("Invalid password");
						getRacesButton.setEnabled(false);
						reserveButton.setEnabled(false);
					}
					
				}
			};
		}
		return login;
	}
	
	private JLabel getErrorLaber() {
		if(errorLaber == null) {
			errorLaber = new JLabel();
			errorLaber.setBounds(34, 168, 649, 25);
		}
		return errorLaber;
	}
	
	private AbstractAction getGetRaces() {
		if(getRaces == null) {
			getRaces = new AbstractAction("Get Scheduled Races", null) {
				public void actionPerformed(ActionEvent evt) {
					try{
						RaceRMIDTO aux=null;
						List<RaceRMIDTO> listRaces = controller.getRaces();
						if (racesTable.getRowCount()>1){
							int i=1;
							while (i<racesTable.getRowCount()){
								racesTableModel.removeRow(1);
							}
						}
						for (int i=0; i<listRaces.size(); i++){
							aux=listRaces.get(i);
							Object[] dat= {aux.getRaceServer(),(String)aux.getName(),Float.toString(aux.getDistance()),(String)aux.getDate(), Integer.toString(aux.getAvailablePlaces())};
							racesTableModel.insertRow(i+1,dat);
						}
						racesTable.setRowSelectionAllowed(true);
						reserveButton.setEnabled(true);
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						errorLaber.setText("Error consulting races");
					} 
				}
			};
		}
		return getRaces;
	}
	
	private AbstractAction getReservePlace() {
		if(reservePlace == null) {
			reservePlace = new AbstractAction("Reserve Place", null) {
				public void actionPerformed(ActionEvent evt) {
					errorLaber.setText("");
					int error=0;
					int fil = racesTable.getSelectedRow();
					String rServer= (String)racesTable.getValueAt(fil, 0);
					String rName= (String)racesTable.getValueAt(fil, 1);
					if (fil==0){
						errorLaber.setText("Choose a valid race please");
						error=1;
					}
					Object aux = racesTable.getValueAt(fil, 4);
					String places = aux.toString();
					try {
						if (places.compareToIgnoreCase("0")!=0){
							controller.reservePlace(rServer, rName);
					}
						else {
						errorLaber.setText("There ara not available places for the selected race");
							error=1;
					}
					} catch (RemoteException e) {
						error=1;
						errorLaber.setText("Error reserving the place");
					} catch (SQLException e) {
						error=1;
						e.printStackTrace();
						errorLaber.setText("You have already a reservation of this race");
					}
					if (error==0){
						errorLaber.setText("The reservation has been successfuly done");
					}
				}
			};
		}
		return reservePlace;
	}
	

	@Override
	public void update(Observable arg0, Object race) {
		if (race instanceof RaceRMIDTO){
			RaceRMIDTO aux =(RaceRMIDTO)race;
			String rName= aux.getName();
			String rServer= aux.getRaceServer();
			boolean finded=false;
			int row=1;
			while (!finded  && row<racesTable.getRowCount()){
				if (racesTable.getValueAt(row, 0).equals(rServer) && racesTable.getValueAt(row, 1).equals(rName)){
					finded=true;
				}
				else {
					row++;
				}
			}
			if (finded){
				racesTable.setValueAt(aux.getAvailablePlaces(), row, 4);
			}
		}
	}
	
	private AbstractAction getExit() {
		if(exit == null) {
			exit = new AbstractAction("Exit", null) {
				public void actionPerformed(ActionEvent evt) {
					try {
						controller.exit();
					} catch (RemoteException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			};
		}
		return exit;
	}
}
